
import React, {Fragment} from "react";
import {Button, Form, Icon, Upload, message, Progress, Card, Table, Result} from "antd";
import XLSX from 'xlsx';
import service from "../../libs/request";
import Store from "../../pages/generate/ordinary/Store";

class ActionImport extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            fileName : props.config.fileName + "." + props.config.format,
            format:props.config.format,
            header:props.config.header,
            map:props.config.map,
            fileList:[],
            //当前导入工作区
            sheet:"",
            //导入进度提示
            processText:"",
            //导入进度
            processPercent:0,
            //失败的行
            errorRows:[],
            showCard:false,
            showError:false,
            status:"success",
            title:"",
            subTitle:"",
        }
    }

    handleImportData = (list) => {
        //处理数据
        const result = [];
        list.map((item,index) => {
            let data = {};
            Object.keys(this.state.map).forEach(key => {
                data[this.state.map[key]] = item.hasOwnProperty(key) && item[key] !== undefined ? item[key] : ""
            });
            result.push(data);
            return true
        });
        return result;
    };

    handleUpload = (file,fileList) => {
        this.setState({
            showCard:false,
            showError:false,
        });
        // 获取文件名称
        let name = file.name;
        // 获取文件后缀
        let suffix = name.substr(name.lastIndexOf("."));

        let reader = new FileReader();
        reader.onload = async (event) => {
            try {
                // 判断文件类型是否正确
                if ("." + this.state.format !== suffix) {
                    message.error("文件类型不正确,请先下载模板填充数据");
                    this.setState({
                        showCard:false,
                        processPercent:0,
                        processText:"",
                        showError:true,
                        status:"error",
                        title:"导入出错",
                        subTitle:"文件类型不正确,请先下载模板填充数据",
                    });
                    return false;
                }

                let {result} = event.target;
                // 读取文件
                let workbook = XLSX.read(result, {type: 'binary'});
                let data = [];
                // 循环文件中的每个表
                for (let sheet in workbook.Sheets) {
                    if (workbook.Sheets.hasOwnProperty(sheet)) {
                        //检查表头，处理数据
                        let result = this.handleImportData(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
                        data = data.concat(result);
                    }
                }
                if (data.length === 0){
                    message.error("导入的数据不能为空");
                    return false;
                }

                this.setState({
                    processText: `上传数据就绪`,
                    processPercent: 0,
                    showCard:true,
                });

                let pages = Math.ceil(data.length / 20);
                let len = data.length;
                for (let i = 0; i < pages; i++) {
                    let start = i * 20;
                    let end = i * 20 + 20 <= len ? i * 20 + 20 : len;
                    let current_data = data.slice(start, end);
                    this.setState({
                        processText: `正在导入第${start}行-第${end}行`,
                    });
                    let res = await service.request({
                        url: this.props.url,
                        method: "post",
                        data: {data:JSON.stringify(current_data)}
                    });
                    if (res.data.code === 200) {
                        let errorRows = res.data.errorRows;
                        this.setState({
                            processText: `第${start}行-第${end}行导入完成`,
                            processPercent:(((i+1)*100)/pages).toFixed(0),
                            errorRows:this.state.errorRows.concat(errorRows)
                        });
                    }
                }

                this.setState({
                    processText: `数据导入成功`,
                });

                if (this.state.errorRows.length === 0){
                    this.setState({
                        showCard:false,
                        processPercent:0,
                        processText:"",
                        showError:true,
                        status:"success",
                        title:"数据导入成功",
                    });
                    Store.fetchRecords();
                }else {
                    this.setState({
                        showCard:false,
                        processPercent:0,
                        processText:"",
                        showError:true,
                        status:"error",
                        title:"导入出错",
                        subTitle:"导入请求过程中发生错误,请联系管理员处理",
                    });
                }
            } catch (e) {
                this.setState({
                    showCard:false,
                    processPercent:0,
                    processText:"",
                    showError:true,
                    status:"error",
                    title:"导入出错",
                    subTitle:"导入请求过程中发生错误,请联系管理员处理",
                });
            }

        };
        reader.readAsBinaryString(file);
        return false;
    };

    handleTemplateDownload = () => {
        service.request({
            url:this.props.config.templateUrl,
            method:"get",
            responseType:'arraybuffer',
            params:{},
        }).then(response => {
            let blob = new Blob([response.data]);
            let downloadElement = document.createElement('a');
            let href = window.URL.createObjectURL(blob); //创建下载的链接
            downloadElement.href = href;
            downloadElement.download = this.state.fileName; //下载后文件名
            document.body.appendChild(downloadElement);
            downloadElement.click(); //点击下载
            document.body.removeChild(downloadElement); //下载完成移除元素
            window.URL.revokeObjectURL(href); //释放掉blob对象
            message.success("模板下载成功")
        })
    };

    render() {
        const columns = [
            {
                title: '失败行',
                dataIndex: 'row',
                key: 'row',
            },
            {
                title: '失败原因',
                dataIndex: 'error_info',
                key: 'error_info',
            },
            {
                title: '数据',
                dataIndex: 'data',
                key: 'data',
                render: data => {
                    return data.length > 20 ? data.substring(0,20) + "..." : data;
                }
            },
        ];
        return (
            <Fragment>
                <Form labelCol={{span: 6}} wrapperCol={{span: 14}}>
                    <Form.Item label="模板下载" help="请下载使用该模板填充数据后导入">
                        <a onClick={this.handleTemplateDownload}>{this.state.fileName}</a>
                    </Form.Item>
                    <Form.Item required label="导入数据">
                        <Upload name="file" accept=".xls, .xlsx" fileList={this.state.fileList}  beforeUpload={this.handleUpload}>
                            <Button>
                                <Icon type="file-excel"/> 点击导入
                            </Button>
                        </Upload>
                    </Form.Item>
                </Form>
                <div style={{width:"546px",margin:"0 auto"}}>
                    {this.state.showCard &&  <Card >
                        <div>{this.state.processText}</div>
                        <Progress
                            strokeColor={{
                                from: '#108ee9',
                                to: '#87d068',
                            }}
                            percent={parseInt(this.state.processPercent)}
                            status="active"
                        />
                    </Card>}
                    {this.state.showError && <Fragment>
                        <Result
                            status={this.state.status}
                            title={this.state.title}
                            subTitle={this.state.subTitle}
                        />
                    </Fragment>}
                    {/*导入结果*/}
                    {this.state.status === "error" && <Table style={{marginTop:"20px"}} columns={columns} dataSource={this.state.errorRows} />}
                </div>
            </Fragment>
        );
    }
}

export default ActionImport;
